﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Web;
using Fx.Mvc.Security.Entities;
using Fx.Data.NHibernate;
using Fx.Utility;
using System.Web.Caching;

namespace Fx.Mvc
{
    /// <summary>
    /// This authentication will be supported in case of checking request is not expired.
    /// Each authentication request comes, we will check in database the request is not expired. 
    /// If expired, redirecting to login page.
    /// </summary>
    public class CookieAuthentication
    {
        private static readonly Cache _cache = HttpRuntime.Cache;
        private static readonly string _TokenName = ".matcuhp";
        private static readonly int _TimeOut = 120;

        #region Token cookie methods
        
        public static void SetTokenToCookie(string userName, bool createPersistentCookie)
        {
            SetTokenToCookie(userName, createPersistentCookie, _TimeOut);
        }

        public static void SetTokenToCookie(string userName, bool createPersistentCookie, int expiresMinutes)
        {
            var token = Guid.NewGuid().ToString();
            var tokenCookie = new HttpCookie(_TokenName, token);
            if (createPersistentCookie)
            {
                tokenCookie.Expires = DateTime.Now.AddMinutes(expiresMinutes);
            }
            else
            {
                tokenCookie.Expires = DateTime.MinValue;
            }
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Response.Cookies.Add(tokenCookie);
            }
            FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
        }

        public static HttpCookie GetTokenFromCookie()
        {
            var current = HttpContext.Current;
            return current != null ? current.Request.Cookies[CookieAuthentication._TokenName] : null;
        }

        #endregion

        #region Token database methods
        
        public static void SetTokenToDatabase(string username, string token, int expiresMinutes)
        {
            var context = new ContextObject();
            var tokenEntity = new Token
            {
                Data = token,
                LoginTime = DateTime.Now,
                UserName = username,
                ExpiredTime = DateTime.Now.AddMinutes(expiresMinutes),
                IsExpired = false,
                Ip = Browser.GetClientIp()
            };
            context.Save(tokenEntity);
            context.CommitChanges();
        }

        public static Token GetTokenFromDatabase(string token)
        {
            var context = new ContextObject();
            var tokenEntity = (from t in context.Queryable<Token>()
                         where !t.IsExpired && t.Data == token
                         select t).FirstOrDefault();
            return tokenEntity;
        }

        #endregion

        public static void SignOut()
        {
            FormsAuthentication.SignOut();
        }
    }
}
